package com.sz.biz.logistics.serialno.service.impl;

import com.sz.biz.logistics.constants.ErrorCodes;
import com.sz.biz.logistics.serialno.constants.BillNumberConstants;
import com.sz.biz.logistics.serialno.constants.BillNumberErrorCodes;
import com.sz.biz.logistics.serialno.entity.SerialNoRuleDetails;
import com.sz.biz.logistics.serialno.service.NoRuleDetailService;
import com.sz.biz.logistics.serialno.utils.EmailValid;
import com.sz.biz.logistics.serialno.utils.TelPhoneValid;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Function: 单号规则详情相关功能实现 <br>
 * Author: Johnboy <br>
 * Date: 2017-12-07 17:12:00
 * @author Johnboy
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class NoRuleDetailServiceImpl extends AbstractService implements NoRuleDetailService {
    
    @Override
    public void save(SerialNoRuleDetails serialNoRuleDetails) {
        validSaveData(serialNoRuleDetails);
        dao.save(getSqlName("insertSelective") , serialNoRuleDetails);
    }

    @Override
    public SerialNoRuleDetails findByRuleId(int ruleId){
      return (SerialNoRuleDetails) dao.findForObject(getSqlName("queryByRuleId"),ruleId);
    }
    
    @Override
    public String findRuleNameByRuleId(String formatRule) {
        return (String) dao.findForObject(getSqlName("findRuleNameByRuleId"), formatRule);
    }
    
    @SuppressWarnings ("AlibabaUndefineMagicConstant")
    @Override
    public void update(SerialNoRuleDetails serialNoRuleDetails) {
        validSaveData(serialNoRuleDetails);
        if ((int) dao.findForObject(getSqlName("findDetailByRuleId"), serialNoRuleDetails.getRuleId()) < 1) {
            throw Exceptions.bizException(
                    BillNumberErrorCodes.ERROR_CHANNEL_RULE_DETAIL_NOT_EXIST);
        }
        dao.update(getSqlName("updateByPrimaryKey"), serialNoRuleDetails);
    }
    
    void validSaveData(SerialNoRuleDetails serialNoRuleDetails) {
        if (serialNoRuleDetails != null) {
            if (serialNoRuleDetails.getCreateMethod().compareTo(
                    BillNumberConstants.RuleCreateMethod.AUTO) == 0) {
                if (serialNoRuleDetails.getBatchNumber() == null || serialNoRuleDetails.getBatchNumber() < 0) {
                    throw Exceptions.bizException(
                            BillNumberErrorCodes.ERROR_CHANNEL_BATCH_NUMBER_ERROR, 1);
                }
                if (serialNoRuleDetails.getGenerateThreshold() == null || serialNoRuleDetails.getGenerateThreshold() <= 0) {
                    throw Exceptions.bizException(
                            BillNumberErrorCodes.ERROR_CHANNEL_GENERATE_THRESHOLD_ERROR, 1);
                }
                if(serialNoRuleDetails.getBatchNumber()<=serialNoRuleDetails.getGenerateThreshold()){
                    throw Exceptions.bizException(BillNumberErrorCodes.ERROR_CHANNEL_RULE_BATCH_GREATER_THAN_THRESHOLD);
                }
            }
            boolean checkCreateMethod = serialNoRuleDetails.getCreateMethod() == null || (
                serialNoRuleDetails.getCreateMethod() != BillNumberConstants.RuleCreateMethod.AUTO
                    && serialNoRuleDetails.getCreateMethod() != BillNumberConstants.RuleCreateMethod.MANUAL);
            if (checkCreateMethod) {
                throw Exceptions.bizException(BillNumberErrorCodes.ERROR_RULE_DETAIL_CREATE_METHOD_ERROR);
            }

            if (serialNoRuleDetails.getCreateMethod().compareTo(
                    BillNumberConstants.RuleCreateMethod.MANUAL) == 0) {
                serialNoRuleDetails.setBatchNumber(null);
                serialNoRuleDetails.setGenerateThreshold(null);
            }
            if (serialNoRuleDetails.getWarnThreshold() != null && serialNoRuleDetails.getWarnThreshold() < 0) {
                throw Exceptions.bizException(
                        BillNumberErrorCodes.ERROR_CHANNEL_RULE_WARNING_THRESHOLD_NOT_BE_NEGATIVE);
            }
            if (StringUtils.isNotEmpty(serialNoRuleDetails.getReceiver())) {
                String receiver = serialNoRuleDetails.getReceiver();
                if (receiver.endsWith(BillNumberConstants.Symbols.SYMBOL_SEMICOLON_EN)) {
                    receiver = receiver.substring(0 , receiver.length() - 1);
                }
                if (receiver.endsWith(BillNumberConstants.Symbols.SYMBOL_SEMICOLON_CN)) {
                    receiver = receiver.substring(0 , receiver.length() - 1);
                }
                serialNoRuleDetails.setReceiver(receiver);
                List<String> results = Arrays.stream(receiver.split(";|；")).collect
                        (Collectors.toList());
                if (BillNumberConstants.ChannelNoticeType.SMS.equalsIgnoreCase(serialNoRuleDetails.getNoticeType())) {
                    for(String str : results) {
                        if (! TelPhoneValid.isPhoneNumber(str)) {
                            throw Exceptions.bizException(
                                    BillNumberErrorCodes.ERROR_CHANNEL_RULE_TELEPHONE_ERROR);
                        }
                    }
                }
                else {
                    for(String str : results) {
                        if (! EmailValid.checkEmail(str)) {
                            throw Exceptions.bizException(
                                    BillNumberErrorCodes.ERROR_CHANNEL_RULE_EMAIL_ERROR);
                        }
                    }
                }
            }
        }else{
            throw Exceptions.bizException(ErrorCodes.ERROR_COMMON,"参数错误");
        }
    }

    @Override
    protected String getMapperNamespace() {
        return "SerialNoRuleDetailsMapper";
    }
}
